package xyz.archknight.app.loginput.dictionary.gen.service

import io.reactivex.rxjava3.subjects.PublishSubject
import io.reactivex.rxjava3.subjects.Subject
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.swing.Swing
import xyz.archknight.app.loginput.dictionary.gen.bean.Packet
import xyz.archknight.app.loginput.dictionary.gen.bean.ActionProtocol
import xyz.archknight.app.loginput.dictionary.gen.bean.DatabaseProtocol
import xyz.archknight.app.loginput.dictionary.gen.bean.StatusProtocol

/**
 * 基于RxJava 3的事件总线，用于在各个界面组件间传递消息
 *
 * @author midnite
 * create at 2020-06-18 10:47 下午
 */
object EventBus {
    private val toolbarActions = PublishSubject.create<Packet<ActionProtocol, Int>>()
    private val databaseChange = PublishSubject.create<DatabaseProtocol>()
    private val statusChange = PublishSubject.create<Packet<StatusProtocol, Long>>()
    private val analysisPhase = PublishSubject.create<String>()
    private val assemblePhases = PublishSubject.create<String>()

    val toolbar: Subject<Packet<ActionProtocol, Int>>
    get() = toolbarActions
    val database: Subject<DatabaseProtocol>
    get() = databaseChange
    val status: Subject<Packet<StatusProtocol, Long>>
    get() = statusChange
    val analysisQueue: Subject<String>
    get() = analysisPhase
    val assemble: Subject<String>
    get() = assemblePhases

    fun sendToolbarAction(action: ActionProtocol, payload: Int = 1) = GlobalScope.launch(Dispatchers.Swing) {
        toolbarActions.onNext(Packet(action, payload))
    }

    fun dbChange(source: DatabaseProtocol) = GlobalScope.launch(Dispatchers.Swing) {
        databaseChange.onNext(source)
    }

    fun refreshStatus(action: StatusProtocol, payload: Long) = GlobalScope.launch(Dispatchers.Swing) {
        statusChange.onNext(Packet(action, payload))
    }

    fun sendAnalysis(phase: String) = GlobalScope.launch(Dispatchers.Swing) {
        analysisPhase.onNext(phase)
    }

    fun assemble(phase: String) = GlobalScope.launch(Dispatchers.Swing) {
        assemblePhases.onNext(phase)
    }
}